from librpg.menu import (Menu, Panel, Label, VerticalScrollArea, Cursor,
                         WidgetGroup, DefaultCursorTheme, ImageWidget,
                         AlignCenter)
from librpg.config import graphics_config as g_cfg
from librpg.locals import UP, RIGHT, LEFT, DOWN, CENTER, SRCALPHA
from librpg.color import YELLOW, RED, GREEN, WHITE
from broadcaster import Listener

from ingame import Ingame
from matchteam import CARD_NONE, CARD_YELLOW, CARD_TWO_YELLOW, CARD_RED
from chalkboard import Chalkboard

import pygame


class SpeedLabel(Label):

    def __init__(self, text, speed):
        Label.__init__(self, text, size=20)
        self.speed = speed

    def activate(self):
        self.menu.change_speed(self.speed)
        return True

    
class ExitLabel(Label):

    def __init__(self):
        Label.__init__(self, 'Exit', size=20)

    def activate(self):
        self.menu.close()
        return True


class CommandPanel(Panel):

    def __init__(self, width, height):
        Panel.__init__(self, width, height)
        
        self.speed_labels = []
        x = 20
        SPACING = 40
        for txt, speed in (('Stop', 0), ('Play', 3), ('Fast', 6),
                           ('Very Fast', 30), ('Crazy', 120)):
            l = SpeedLabel(txt, speed)
            self.add_widget(l, (x, self.height/2, LEFT, CENTER))
            self.speed_labels.append(l)
            x += SPACING + l.width

    def enable_exit(self):     
        for w in self.speed_labels:   
            self.remove_widget(w)
        
        exit_label = ExitLabel()
        self.add_widget(exit_label, (20, self.height/2, LEFT, CENTER))


class TeamPanel(Panel):
    
    def __init__(self, match_team, width, height):
        Panel.__init__(self, width, height)
        self.match_team = match_team
        
        self.refresh()
        
    def refresh(self):
        ws = self.get_contents()
        for w in ws:
            self.remove_widget(w)
        
        l = Label(self.match_team.team.name, focusable=False, bold=True)
        y = 15
        self.add_widget(l, (15, y))
        y += 24
        
        GROUP_SPACING = 15
        for match_player in self.match_team.match_players:
            l1 = Label('%2d' % match_player.number, size=12, color=YELLOW)
            l2 = Label('%s' % match_player.player.name, size=12)
            group_h = max(l1.height, l2.height)
            player_group = WidgetGroup(self.width - 2 * GROUP_SPACING, group_h)
            player_group.add_widget(l1, (0, 0))
            player_group.add_widget(l2, (25, 0))
            
            surf = self.get_card_image(match_player)
            if surf != None:
                i = ImageWidget(surf)
                player_group.add_widget(i, (player_group.width - 25,
                                            group_h / 2,
                                            LEFT,
                                            CENTER))
            
            surf = self.get_goal_image(match_player)
            if surf != None:
                i = ImageWidget(surf)
                x = player_group.width - 60
                player_group.add_widget(i, (x,
                                            group_h / 2,
                                            LEFT,
                                            CENTER))
                l = Label(str(match_player.goals), size=12)
                player_group.add_widget(l, (x + i.width + 2,
                                            group_h / 2,
                                            LEFT,
                                            CENTER))
            
            self.add_widget(player_group, (GROUP_SPACING, y))
            y += group_h

    CARD_WIDTH = 10
    CARD_HEIGHT = 12
    TWO_YELLOW_CARDS_SPACING = 2
    FIRST_CARD_RECT = pygame.Rect(0, 0, CARD_WIDTH, CARD_HEIGHT)
    SECOND_CARD_RECT = pygame.Rect(CARD_WIDTH + TWO_YELLOW_CARDS_SPACING, 0,
                                   CARD_WIDTH, CARD_HEIGHT)

    def get_card_image(self, match_player):
        if match_player.card == CARD_NONE:
            return None
        else:
            wh = (2 * TeamPanel.CARD_WIDTH + TeamPanel.TWO_YELLOW_CARDS_SPACING,
                  TeamPanel.CARD_HEIGHT)
            s = pygame.Surface(wh, SRCALPHA, 32)
            if match_player.card == CARD_YELLOW:
                pygame.draw.rect(s, YELLOW, TeamPanel.FIRST_CARD_RECT, 0)
            elif match_player.card == CARD_TWO_YELLOW:
                pygame.draw.rect(s, YELLOW, TeamPanel.FIRST_CARD_RECT, 0)
                pygame.draw.rect(s, YELLOW, TeamPanel.SECOND_CARD_RECT, 0)
            elif match_player.card == CARD_RED:
                pygame.draw.rect(s, RED, TeamPanel.FIRST_CARD_RECT, 0)
            return s
    
    def get_goal_image(self, match_player):
        if match_player.goals == 0:
            return None
        else:
            BALL_WIDTH = 12
            HALF_BALL_WIDTH = BALL_WIDTH / 2
            wh = (BALL_WIDTH, BALL_WIDTH)
            s = pygame.Surface(wh, SRCALPHA, 32)
            pygame.draw.circle(s, WHITE, (HALF_BALL_WIDTH, HALF_BALL_WIDTH),
                               HALF_BALL_WIDTH)
            return s


class EventArea(VerticalScrollArea):
    
    EVENT_COLORS = {'yellow_card':YELLOW, 'red_card':RED, 'goal':GREEN}
     
    def __init__(self, width, height):
        VerticalScrollArea.__init__(self, width, height, 20)

    def add(self, event):
        n = self.add_line()
        new_div = self[n]
        self.go_to_end()
        color = EventArea.EVENT_COLORS.get(event.type, None)
        l = Label(str(event), color=color)
        new_div.add_widget(l, (0, 0))
        

class MatchPanel(Panel):
    
    def __init__(self, ingame, width, height):
        Panel.__init__(self, width, height)
        self.ingame = ingame
        
        SPACING = 20
        y = 25
        
        x = SPACING
        self.time_label = Label('xx minutes', focusable=False, size=16)
        self.add_widget(self.time_label, (x, y, LEFT, CENTER))
        x += self.time_label.width + SPACING
        
        self.score_label = Label('', focusable=False, size=20)
        self.add_widget(self.score_label, (x, y, LEFT, CENTER))
        
        y += SPACING
        self.event_area = EventArea(width - 2 * SPACING, height - y - SPACING)
        self.add_widget(self.event_area, (SPACING, y))
        
    def update(self):
        ig = self.ingame
        
        t = ig.watch.total_minutes
        txt = '%d minute%s' % (t, '' if t == 1 else 's')
        self.time_label.text = txt
        
        txt = '%s %dx%d %s' % (ig.match_teams[0].team.name,
                               ig.match_teams[0].score,
                               ig.match_teams[1].score,
                               ig.match_teams[1].team.name)
        self.score_label.text = txt


class ChalkboardPanel(Panel):

    def __init__(self, ingame, width, height):
        Panel.__init__(self, width, height, focusable=False)
        
        self.chalkboard = Chalkboard(ingame, 280, 400)
        self.add_widget(self.chalkboard, AlignCenter())


class MatchMenu(Menu, Listener):
    
    def __init__(self, match):
        self.match = match
        
        w, h = g_cfg.screen_dimensions
        Menu.__init__(self, w, h)

        self.ingame = Ingame(match.match_team1, match.match_team2)
        self.ingame.register(self)
        
        self.team_panels = []
        
        SPACING = 10
        TEAM_PANELS_H = 230
        
        COMMAND_PANEL_H = 50
        
        team_panel = TeamPanel(match.match_team1, (w - 3 * SPACING) / 2,
                               TEAM_PANELS_H) 
        self.add_widget(team_panel, (SPACING, SPACING))
        self.team_panels.append(team_panel)
        
        team_panel = TeamPanel(match.match_team2, (w - 3 * SPACING) / 2,
                               TEAM_PANELS_H) 
        self.add_widget(team_panel, (SPACING, self.team_panels[0].bottom + SPACING))
        self.team_panels.append(team_panel)
        
        self.match_panel = MatchPanel(self.ingame, w - 2 * SPACING,
                                      h - 2 * TEAM_PANELS_H - 5 * SPACING - COMMAND_PANEL_H)
        self.add_widget(self.match_panel, (SPACING, 2 * TEAM_PANELS_H + 3 * SPACING))
        
        self.command_panel = CommandPanel(w - 2 * SPACING, COMMAND_PANEL_H)
        self.add_widget(self.command_panel, (SPACING, h - SPACING, LEFT, DOWN))
        
        self.chalkboard_panel = ChalkboardPanel(self.ingame,
                                                (w - 3 * SPACING) / 2,
                                                2 * TEAM_PANELS_H + SPACING)
        self.add_widget(self.chalkboard_panel, (w - SPACING, SPACING, RIGHT, UP))
        
        cursor = Cursor(DefaultCursorTheme(border=1, horizontal_offset=0,
                                           vertical_offset=0))
        cursor.bind(self)
        
        self.speed = None
        self.command_panel.speed_labels[2].activate()

    def listen(self, ig, event):
        if event.type == 'end_of_game':
            self.match.set_result(ig.match_teams[0].score,
                                  ig.match_teams[1].score)
            self.command_panel.enable_exit()
            self.change_speed(0)
        else:
            self.match_panel.event_area.add(event)
        for team_panel in self.team_panels:
            team_panel.refresh()

    def update(self):
        for _ in xrange(self.speed):
            ig = self.ingame
            ig.update()
    
            for team_panel in self.team_panels:
                team_panel.update()
            self.match_panel.update()

    def change_speed(self, new_speed):
        for l in self.command_panel.speed_labels:
            l.color = YELLOW if l.speed == new_speed else WHITE
        self.speed = new_speed
